package com.imooc.zk.demo;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;

import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooDefs.Ids;
import org.apache.zookeeper.ZooDefs.Perms;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.data.ACL;
import org.apache.zookeeper.data.Id;
import org.apache.zookeeper.data.Stat;

import com.imooc.utils.AclUtils;

/**
 * zookeeper 操作节点acl演示
 * 
 * @author wb0024
 *
 */

public class ZKNodeACL implements Watcher {

	public static String zkServerPath = "47.104.64.192:2181";
	public static final Integer timeout = 5000;
	public static Stat stat;
	private ZooKeeper zookeeper = null;
	private static CountDownLatch countDown = new CountDownLatch(1);

	public ZKNodeACL() {
	}

	public ZKNodeACL(String zkserverpath) {
		try {
			zookeeper = new ZooKeeper(zkserverpath, timeout, new ZKNodeACL());
		} catch (IOException e) {
			e.printStackTrace();
			if (zookeeper != null) {
				try {
					zookeeper.close();
				} catch (InterruptedException e1) {
					e1.printStackTrace();
				}
			}
		}
	}

	/**
	 * 
	 * @Title: ZKOperatorDemo.java
	 * @Description: 创建zk节点
	 */
	public void createZKNode(String path, byte[] data, List<ACL> acls) {
		String result = "";
		try {
			/**
			 * 同步或者异步创建节点，都不支持子节点的递归创建，异步有一个callback函数 参数： path：创建的路径 data：存储的数据的byte[]
			 * acl：控制权限策略 Ids.OPEN_ACL_UNSAFE --> world:anyone:cdrwa CREATOR_ALL_ACL -->
			 * auth:user:password:cdrwa createMode：节点类型, 是一个枚举 PERSISTENT：持久节点
			 * PERSISTENT_SEQUENTIAL：持久顺序节点 EPHEMERAL：临时节点 EPHEMERAL_SEQUENTIAL：临时顺序节点
			 */
			result = zookeeper.create(path, data, acls, CreateMode.PERSISTENT);

			// String ctx = "{'create':'success'}";
			// zookeeper.create(path, data, acls, CreateMode.PERSISTENT,new CreayeCallBack()
			// , ctx);

			System.out.println("创建节点：\t" + result + "\t成功...");
			new Thread().sleep(2000);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	/**
	 * 
	 * @Title: ZKOperatorDemo.java
	 * @Description: 修改zk节点
	 */
	public void updateZKNode(String path, byte[] data, Integer version) {
		String result = "";
		try {
			/**
			 * 同步或者异步修改节点，都不支持子节点的递归创建，异步有一个callback函数 参数： path：节点路径 data：数据 version：数据状态
			 */
			// Stat status= zookeeper.setData(path, data,version);
			// System.out.println(status.getVersion());

			String ctx = "{'update':'success'}";
			zookeeper.setData(path, data, version, new UpdateCallBack(), ctx);

			System.out.println("修改节点：\t" + result + "\t成功...");
			new Thread().sleep(2000);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public static void main(String[] args) throws Exception {
		ZKNodeOperator zkServer = new ZKNodeOperator(zkServerPath);

		// //创建节点
		// zkServer.createZKNode("/aclimooc", "test".getBytes(),Ids.OPEN_ACL_UNSAFE);
        
		//自定义用户认证访问
//		List<ACL> acls = new ArrayList<>();
//		Id imooc1 = new Id("digest", AclUtils.getDigestUserPwd("imooc1:123456"));
//		Id imooc2 = new Id("digest", AclUtils.getDigestUserPwd("imooc2:123456"));
//		acls.add(new ACL(Perms.ALL,imooc1));
//		acls.add(new ACL(Perms.READ,imooc1));
//		acls.add(new ACL(Perms.DELETE | Perms.CREATE ,imooc2));
		
		
		//注册过的用户必须通过addAuthInfo才能操作节点，参考命令行 addauth
//		zkServer.getZookeeper().addAuthInfo("digest", "imooc002:123456".getBytes());
		zkServer.getZookeeper().addAuthInfo("digest", "imooc2:123456".getBytes());
	
//		zkServer.createZKNode("/aclimooc/testdigest", "testdigest".getBytes(), Ids.CREATOR_ALL_ACL);
//		Stat stat = new Stat();
//		byte [] data = zkServer.getZookeeper().getData("/aclimooc/testdigest", false, stat);
//		System.out.println(new String(data));
		zkServer.getZookeeper().setData("/aclimooc/testdigest", "new".getBytes(), 1);
		
		
//		//ip方式的acl
//		List<ACL> aclsIP = new ArrayList<>();
//		Id ipId1 = new Id("ip","192.168.1.6");
//		aclsIP.add(new ACL(Perms.ALL, ipId1));
//		zkServer.createZKNode("/aclimooc/testdigest", "new".getBytes(), aclsIP);
		
		//验证ip是否有权限
//		zkServer.getZookeeper().setData("/imooc/iptest", "123456".getBytes(), 0);
		Stat stat = new Stat();
		byte[] data = zkServer.getZookeeper().getData("/aclimooc/iptest6", false, stat);
	    System.out.println(new String(data));
	    System.out.println(stat.getVersion());
	}

	private ZooKeeper getZookeeper() throws IOException {
		ZooKeeper keeper = new ZooKeeper(zkServerPath, timeout, new ZKNodeACL());
		return keeper;
	}

	@Override
	public void process(WatchedEvent event) {
		
	}

}
